//
//  main.c
//  c_pr
//
//  Created by chenyh on 2021/1/18.
//

#include <stdio.h>
/**
 C变量有三种链接属性：外部链接、内部链接 或 无链接
 C对象有4种存储器：静态存储器、线程存储器、自动存储器、动态分配存储器
 */

/*
int giants = 5; //文件作用域： 外部链接
static int dogers = 3;//文件作用域： 内部链接
int x = 12;
int y ;
//x是变量 所以不能赋值为2*x
//int x2 = 2 * x;


int units = 1;
void critic(void);


int main(int argc,const char * argv[]) {
    printf("xxx\n");
    
    printf("%d",x*y);
    
    extern int units;//可选的重复声明
    printf("%d",units);
    scanf("%d",&units);
    while (units !=56)
        critic();
    printf("You must have looked it up!");
    return 0;
}
void critic(void) {
    //删除了可选的重复声明
    printf("No Luck. my firend. Try again.\n");
    scanf("%d",&units);
}

*/


/**
#include <stdlib.h>

extern unsigned int rand0(void);
int main(void)
{
    int count;
    for (count = 0; count < 5; count++) {
        printf("%d\n",rand0());
    }
    return 0;
}
 */
/**
extern void srand1(unsigned int x);
extern int rand1(void);
int main(void)
{
    int count;
    unsigned seed;
    printf("Please enter your choice for seed.");
    while (scanf("%u",&seed) == 1) {
        srand1(seed); // 重置种子
        for (count = 0; count < 5; count++) {
            printf("%d\n",rand1());
        }
        printf("Please enter next seed (q to quit):\n");
    }
    printf("Done \n");
    return 0;
}
 */
/**
 int count = 0; //文件作用域,外部链接
 void report_count(void);
 void accumulate(int k);
int main(int argc,const char * argv[]) {
    int value; //自动变量
    register int i; //寄存器变量
    printf("Enter a positive integer (0 to quit):");
    
    while (scanf("%d",&value) == 1 && value > 1)
    {
        ++count; //使用文件作用域变量
        for (i = value; i >= 0; i--)
            accumulate(i);
        printf("Enter a positive integer (0 to quit):");
    }
    
    report_count();
    return 0;

}

void report_count() {
    printf("Loop executed %d times\n",count);
}
*/

#include <stdlib.h>
//30个double类型的值请求内存空间。并设置ptd指向该位置
/**
int main(void)
{
    //
    double * ptd;
    int max;
    int number;
    int i = 0;
    puts("What is the maximum number of type double entries?");
    
    if (scanf("%d",&max) != 1) {
        puts("Number not correctly entered -- bye.");
        exit(EXIT_FAILURE);
    }
    ptd = (double *)malloc(max * sizeof(double));
    if (ptd == NULL) {
        puts("Memory allocation failed. Goodbye.");
        exit(EXIT_FAILURE);
    }
    //ptd现在指向有max个元素的数组
    puts("Enter the values (q to quit):");
    while (i < max && scanf("%lf",&ptd[i])==1) {
        i++;
    }
    printf("Here are your %d entries: \n)",number = i);
    for (i = 0; i < number; i++) {
        printf("%7.2f",ptd[i]);
        if (i % 7 == 6 ) {
            putchar('\n');
        }
    }
    if (i % 7 != 0) {
        putchar('\n');
    }
    puts("Done.");
    free(ptd);
 
    return 0;
}
 */
//const 是限定指针本身还是限定指向的值为const

/**
1、 const float * pf; // *pf指向一个float类型的const值
    float const * pfc;
 创建了pf指向的值不能被改变，而pt本身的值可以改变。例如，可以设置该指针指向其它const
 值
2、float * const pt; // *pt是一个const的指针
 创建的指针pt本身的值不能更改，pt必须指向同一个地址，但是它所指向的值可以改变。
3、const float * const ptr；标明ptr既不能指向别处，它所指向的值也不能改变。
 把const放在类型名之后、*之前，说明该指针不能用于改变它指向的值。
 把const放在*左侧任意位置，限定了指针指向的数据不能改变；
 把const放在*的右侧，限定了指针本身不能改变。 float * const c;
 */

int main(void)
{
    
    //简单的来说 const在*之前 就是指针变量指向的地址不可修改 但是指向的值是可以修改的
    // *在const之后 就是指针指向的地址可以修改，但是指向的值不可以修改
/**   void*型指针在自增时，是按照一个字节的跨度来计算的。
         int a[3] = {1,2,3};
         void *p = a;
         printf("1:p=0x%x \n",p);
         p=p+1;
         printf("2:p=0x%x \n",p);
 */

    int a[3] = {1, 2, 3};
    int (*p2)[3] = a;
    printf("0x%x \n", a);
    printf("0x%x \n", &a);
    printf("0x%x \n", p2);
    /*思考一下，如果对这里的p2指针执行p2 = p2 + 1;操作，p2中的值将会增加多少？
     
     答案是12个字节。因为p2指向的是一个数组，这个数组中包含3个元素，每个元素占据4个字节，那么这个数组在内存中一共占据12个字节，因此p2在加1之后，就跳过12个字节。*/
    p2 = p2 + 1;
    printf("0x%x \n", p2);
}
